package com.winter.boot.web;

import com.winter.boot.web.handler.HttpServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;

public class Server {

    private Server() {
    }

    private static final Server server = new Server();

    public static Server getServer() {
        return server;
    }

    private final EventLoopGroup boss = new NioEventLoopGroup(1); //接收连接

    private final EventLoopGroup worker = new NioEventLoopGroup(16); //处理客户端读写, cpu核心*2

    public void start() {

        ServerBootstrap serverBootstrap = new ServerBootstrap()
                .group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE) //地址可以复用
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE) //如果是false 底层会积累数据后发送，会造成延迟
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) //ByteBuf的分配器 内存管理模式
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {

                        ChannelPipeline ph = ch.pipeline();
                        //把应答报文 编码
                        ph.addLast("encoder", new HttpResponseEncoder());
                        //把请求报文 解码
                        ph.addLast("decoder", new HttpRequestDecoder());

                        //聚合http为一个完整的报文
                        ph.addLast("aggregator",
                                new HttpObjectAggregator(10 * 1024 * 1024));
                        //把应答报文 压缩,非必要
                        ph.addLast("compressor", new HttpContentCompressor());

                        ph.addLast(new HttpServerHandler());
                    }
                });
        try {
            serverBootstrap.bind(8080).sync();
            System.out.println("服务器启动完毕...");
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    public boolean stop() {
        return false;
    }
}
